# -*- coding:utf-8 -*-
"""
作者：祁康伟
日期：2024/01/12  09:45
"""
import queue
# _*_ coding:utf-8 _*_
# @Time :2022/8/12 10:18
# @File :  producer_yuqidong.py
# @Author :QiKangwei
from enum import Enum
import binascii
import json
import copy
import logging
import os
import struct
import threading
import time
import traceback
from datetime import datetime
import numpy as np
import pandas as pd
import requests
import socket, subprocess
# from scapy.all import *
from api import utils
from api.pojie_A10.computing_method_A10 import XOR_verification, standardized_sampling, calculate_statistical_values, calculate_the_actual_temperature_value, real_time_value_of_pressure_and_velocity, \
    nozzle_temperature_1_8, actual_settings_pressure_speed
from api.pojie_A10.connect_mysql import connect_sql
from api.pojie_A10.producer_set_values_A10 import SampleProducer_set_A10
from api.pojie_A10.settings_pojie_A10 import chinese_source
from api.pojie_A10.producer_set_values_A10 import SampleProducer_set_A10
from api.serial import sample
from api.serial.rebuild_onehour import rebuild_onehour
from detecter import settings

logger = logging.getLogger('pojie_A10.producer_actual_values_A10')
set_yichang_time = 200


class SampleProducer_actual_values_A10(threading.Thread):
    __instance = None

    def __init__(self, ip, port, com, baud, current_mould):
        super().__init__()
        self.setName('SampleProducer_actual_values_A10')
        self.__running = threading.Event()  # 用于停止线程的标识
        self.__data_bytes = bytearray()  # 全局字节数组,串口数据缓冲区
        self.__data_bytes_part = bytearray()  # 全局字节数组,串口数据缓冲区
        self.new_circle_first = True  # 在这里初始值无论为True还是False对项目都没有影响，因为第一模数据是会被筛掉的(就先将其设为True)。当第二模数据开始时，会将这个值更新为True。
        self.socket_TF = True
        self.recv_handle_queue = queue.Queue(30000)
        self.process_queue = settings.process_queue
        self.q = queue.Queue(30000)
        self.__sample_list = []  # 样本队列
        self.__sample_list1 = []  # 样本队列
        self.jishu = 0
        self.current_mould = current_mould
        # ##############   操作板相关   ###############
        self.time_yichang = ''  # 检测到的消费者线程第一次异常的时刻
        self.is_yichang = True  # 用于标志消费者线程是否处于异常状态
        self.sample_frame_list_downsampling = []  # 周期帧数据列表
        self.sample_frame_list_for_other_TF = False
        self.sample_frame_list_TF = False

        # 以下字段类数据，不取最后的00（若干组00） + 校验码（暂不清楚是哪种校验码）
        # # 02009000————设置字段信息（有更改即发送数据，32位）  ————————————————在另一线程采集该信息
        # # 02004E00————实时温度数据（2.5HZ，88位）
        # # 02009001————射胶过程实时压力、速度（10HZ，24位）
        # # 020098014243————实时机台信号数据，其中有设定压力、设定速度，（5HZ，52位）
        # # 0200314542————统计时间、起点、终点、压力、速度，（2.5Hz，104位）
        self.Verification_List = ["02003C00", "02004E00", "02009001", "0200980100**4243"]
        # self.temporary_data = []
        self.Verification_List_set = ["02000900", "02008802"]
        # 与上面字段一一对应，确定每种字段多少个字
        self.Verification_List_del_len = [120 * 2, 156 * 2, 800 * 2, 816 * 2]

        self.computer_board_timing = 0  # 统计参数 13、14位 周期计时
        self.signal_data_computer_board_timing = 0  # 信号数据 69、70位 周期计时
        self.statistical_parameter_row_identification = {"周期计时": "", "注射保压时间": "", "射出时间": "", "储料时间": "", "合模时间": "",
                                                         "合模低压时间": "", "合模高压时间": "", "开模时间": "", "开模位置": "", "射胶信号": "",
                                                         "射出终点": "", "射出监控": "", "射出起点": "", "转保压力": "", "最大储料转速": "",
                                                         "射退时间": "", "托模时间": "", "射出尖压": "", "储料尖压": "", "顶进时间": "",
                                                         "顶退时间": "", "取件时间": "", "最大射速": "", "保压时间": "", "冷却时间": "",
                                                         }  # 这里的设置值json文件可改动
        self.statistical_parameter_row_identification_True = None  # 用于统计参数中，一模产品完成后，参数的记录

        # #############  电脑板统计参数  #############
        # 实时温度数据                                全过程
        self.real_time_temperature_data = {"tmp0": "", "tmp1": "", "tmp2": "", "tmp3": "", "tmp4": "", "tmp5": "", "tmp6": "", "tmp7": "", "tmp8": "", }  # 实时温度数据

        # 实时压力、速度  设定压力 设定速度                全过程
        self.actual_settings_pressure_speed_list = []  # 里面存储的也是一个个列表

        # 实时机台信号数据                                  全过程
        self.processing_signal_data_list = []

        # ##############   分类采集   ###############
        self.conn = None
        self.collection = None
        self.thread_collection = None
        self.stop_sniffing = False

        # ##############   网口采集传输数据   ###############
        self.ip = ip
        self.port = port

        # ##############   串口采集传输数据   ###############
        self.com = com
        self.baud = baud

        self.scqd = []
        self.scjy = []
        self.cljy = []
        self.zdss = []

        self.global_shejiaobaoyafendaun = []
        self.machine_status = ""

    @classmethod
    def new_instance(cls, current_mould):
        # por1 = 51501  # 控制板——设定数据
        # por2 = 52501  # 操作板——实时数据
        cls.__instance = SampleProducer_actual_values_A10("192.168.3.124", 8888, None, None, current_mould)  # 这里传入的ip和端口根本就没有用，因为后直接监听的是网口
        return cls.__instance

    @classmethod
    def get_instance(cls):
        return cls.__instance

    def get_sample_list(self):
        return self.__sample_list

    def get_sample_list1(self):
        return self.__sample_list1

    def is_producer_running(self):
        return self.__running.is_set()

    def begin(self):
        if not self.is_alive():
            self.__running.set()
            self.setDaemon(False)  # 不设置守护线程, 就算websocket挂了也继续收集数据,处理数据, 存入临时文件中, 直到停止本工单才算停止此线程
            self.start()
            t = threading.Thread(target=self.handle_temporary_data)
            t.setDaemon(False)
            t.start()

    # 其实这个函数可以不写，项目中期的时候提出 采集线程一直工作
    def stop(self):
        if self.is_alive():
            self.stop_sniffing = True
            self.socket_TF = False
            # if self.ip:
            #     self.conn.close()
            # self.collection.close()
            self.__running.clear()  # 设置为False

    def transfer_sample(self, current_sample):
        current_mould = self.current_mould
        current_consumer = current_mould.consumer  # 获取建模与检测线程这个对象
        if current_consumer.is_consumer_running():  # 如果消费者正在运行
            self.__sample_list.append(current_sample)  # 将样本添加到样本队列中
        else:  # 如果消费者未处于运行中
            logger.info('消费者consumer未处于运行中')
            utils.undetect_handler(current_mould, current_sample, current_mould.unassigned_file)  # 将未被消费的样本及相关信息进行临时处理
            if self.is_yichang:
                self.time_yichang = time.time()
                self.is_yichang = False
            # 如果异常超过1小时，则自动建模
            if round(time.time() - self.time_yichang, 2) >= set_yichang_time:
                # close_consumer(current_mould)
                rebuild_onehour(current_mould.mould_code)

    def run(self):
        # global sample_frame_list_for_other_TF,sample_frame_list_TF
        # data_bytes = self.__data_bytes_part
        # is_first_collection = True
        # count = 1024  # 返回接收缓存中的字节数
        is_first_sample = True
        data_flag = False
        pressure_size = 8  # 用作判别、确认字段信息的长度
        frame_rate = 5  # 机台采集数据的频率(计算周期字段的数据频率)，1s有多少帧数据传过来      帧数可以被算出来   由于网络因素或其他，这个值可以是动态变化的
        frame_bytes_list = []  # 异常帧数据列表
        last_50_cycles = []  # 存最近50个周期，以用作计算标准周期
        zhenshu = 10  # 测试帧数  需要测试多少帧
        standard_cycle = 0
        # sample_id = -1
        # sample_frame_list_for_other_TF = False
        # sample_frame_list_TF = False
        self.thread_collection = threading.Thread(target=self.receive_packets, args=(self.socket_TF,))
        self.thread_collection.start()
        while self.__running.is_set():
            while self.q.qsize() >= 1:  # 队列里面有一条以上的数据
                # snapshot1=tracemalloc.take_snapshot()
                # frame_bytes = data_bytes[0:int(16 / 2)].hex().upper()  # 16位
                data_bytes = self.q.get()  # 得到的是一个字节型数据

                # with open("//usr//local//src//webroot//detecter//data//test200.txt", "a+") as f:  ##不要在这里进行写操作，耗时严重，会严重丢帧！！！！！！！！！！！
                #     f.write(data_bytes.hex().upper() + "\n")
                #     print("成功写入！")

                frame_bytes = data_bytes[0:int(16 / 2)].hex().upper()  # 16位
                if frame_bytes[:10] == self.Verification_List[3][:10]:
                    whether_to_parse, del_size = True, int(self.Verification_List_del_len[3] / 2)
                else:
                    whether_to_parse, del_size = self.verify_dictionary(frame_bytes[:8], self.Verification_List, self.Verification_List_del_len)

                # 防止帧数据不完整
                if len(data_bytes[0:del_size]) != del_size:
                    whether_to_parse = False
                    # del_size = len(data_bytes[0:del_size])
                    logger.info("帧数据数据不完整")

                if not data_flag:
                    logger.info("SampleProducer_actual_values_A10 received data!")
                    data_flag = True

                # 若标识字段在所要解析的列表中时，根据该标识拿到字节长度即是后面所删除的字长度
                if whether_to_parse:
                    frame_bytes = data_bytes.hex().upper()  # 拿到对应字段信息长度数据
                    # with open("//usr//local//src//webroot//detecter//data//test217.txt", "a+") as f:  ##不要在这里进行写操作，耗时严重，会严重丢帧！！！！！！！！！！！
                    #     f.write(frame_bytes[:32])
                    #     f.write("哈哈哈哈哈\n")
                    #     print("成功写入！")
                    # 数据过滤、异或校验
                    if XOR_verification(frame_bytes[4:-6]) == frame_bytes[-6:-4]:
                        # 不是自动、半自动状态的    不进行采集
                        if frame_bytes[24:26] == "03":
                            self.machine_status = "半自动"
                        elif frame_bytes[24:26] == "09":
                            self.machine_status = "全自动"
                        elif frame_bytes[24:26] == "00":
                            self.machine_status = "手动"
                        if frame_bytes[:pressure_size] == "02009001" and frame_bytes[24:26] not in ["03", "09"]:
                            # print("不是自动、半自动状态，不进行采集")
                            # data_bytes.clear()  # 直接对整个data_bytes.clear()进行了清空，没有问题吗？怎么确定data_bytes中没被取出来的数据也是不需要的？
                            self.del_data()
                            self.actual_settings_pressure_speed_list = []
                            self.processing_signal_data_list = []
                            is_first_sample = True
                            logger.info("不是自动、半自动状态，不进行采集,is_first_sample的值为{}".format(is_first_sample))
                            continue

                        # 将数据添加到指定列表
                        try:
                            self.add_data_to_list(frame_bytes, pressure_size)
                        except:
                            logger.info(traceback.format_exc())

                        # 检测缓存数据量，如果数据存量有30分钟帧数量，则清理压力帧数据缓存列表
                        if len(self.processing_signal_data_list) >= frame_rate * 60 * 30 or len(self.actual_settings_pressure_speed_list) >= frame_rate * 60 * 30:  # 一秒多少帧  一分钟60秒  以30分钟做限制
                            # data_bytes.clear()
                            self.del_data()
                            self.actual_settings_pressure_speed_list = []
                            self.processing_signal_data_list = []
                            is_first_sample = True
                            logger.info("清理缓存,is_first_sample的值为{}".format(is_first_sample))
                            continue
                        frame_list_len = len(self.processing_signal_data_list)
                        if frame_list_len >= 5:
                            check_frame_list = self.processing_signal_data_list[frame_list_len - 5:frame_list_len]
                            if self.is_product_begin(check_frame_list):
                                sample_frame_list = self.processing_signal_data_list[:frame_list_len - 4]  # 包含最后一帧
                                # 当合模信号确认后，直接删除对应列表中的存储信息
                                del self.processing_signal_data_list[0:len(self.processing_signal_data_list) - 4]  # 保留下一帧开始的4帧没有丢失
                                self.sample_frame_list_TF = True  # 标志机台实时动作信号这个数据  拿到了周期分割点之前的数据(也可以说是一个周期的数据)
                                logger.info('边缘计算的合模信号结束')  # j 从抓到的原始数据来看，每次都是边缘计算的合模信号先开始先结束

                        frame_list_len_for_other = len(self.actual_settings_pressure_speed_list)
                        if frame_list_len_for_other >= 5:
                            check_frame_list_for_other = self.actual_settings_pressure_speed_list[frame_list_len_for_other - 5:frame_list_len_for_other]
                            if self.is_product_begin_for_other(check_frame_list_for_other):
                                sample_frame_list_for_other = self.actual_settings_pressure_speed_list[:frame_list_len_for_other - 4]  # 包含最后一帧
                                # 当合模信号确认后，直接删除对应列表中的存储信息
                                del self.actual_settings_pressure_speed_list[0:len(self.actual_settings_pressure_speed_list) - 4]  # 保留下一帧开始的4帧没有丢失
                                self.sample_frame_list_for_other_TF = True  # 标志设置实际设置压力速度这个数据  拿到了周期分割点之前的数据(也可以说是一个周期的数据)
                                logger.info('工艺参数的合模信号结束')

                                # if self.sample_frame_list_for_other_TF and self.sample_frame_list_TF:  # 如果这两个列表都获取了一个周期的数据
                                #     self.sample_frame_list_for_other_TF = False
                                #     self.sample_frame_list_TF = False
                                # else:
                                #     logger.info('两种信号的合模信号不一致，结束了此次循环，进入了下一次循环')
                                #     continue  # 跳过此次的while循环的时候，不删除data_bytes里面的数据吗？  每次都会从data_bytes里面的第一条数据开始取值？
                                # 除掉第一个样本(第一个样本无法收集到全部帧信息),虽然第一个样本不计入，但是模具下的样本id还是进行了加1
                                sample_id = self.current_mould.add_sample()
                                if is_first_sample:
                                    is_first_sample = False
                                    logger.info("采集到第一个样本，不计入，跳过")# 跳过的时候，不将
                                else:
                                    try:
                                        if len(last_50_cycles) < zhenshu:
                                            logger.info("周期列表个数{}，未到{}，周期帧数不做限制".format(len(last_50_cycles), zhenshu))
                                            last_50_cycles.append(len(sample_frame_list) / frame_rate)
                                            if len(last_50_cycles) == zhenshu:
                                                standard_cycle = self.statistical_cycle_interval(last_50_cycles, zhenshu)

                                        elif len(last_50_cycles) == zhenshu:
                                            logger.info("周期列表个数{}，到{}，周期帧数限制".format(len(last_50_cycles), zhenshu))
                                            last_50_cycles.append(len(sample_frame_list) / frame_rate)
                                            last_50_cycles.pop(0)
                                            standard_cycle = self.statistical_cycle_interval(last_50_cycles, zhenshu)
                                            logger.info("落在多数区间的上限值是{}s".format(standard_cycle))

                                        # 大于标准周期的2倍，并且周期列表中有50个样本   不传输周期数据
                                        if len(sample_frame_list) >= standard_cycle * frame_rate * 2 and len(last_50_cycles) == zhenshu:
                                            logger.info("2倍区间上限是{}".format(standard_cycle * frame_rate * 2))
                                            logger.info("该样本帧数长度为{}".format(len(sample_frame_list)))
                                            # 将该样本的帧数据存入文件夹中
                                            # with open("//usr//local//src//webroot//detecter//data//error_sample.csv", "w") as f:
                                            with open(os.path.join(os.getcwd(), "error_sample.csv"), "w") as f:
                                                f.writelines("产品id为{}的帧数据量异常，存入异常文件中，不向Java传输周期数据".format(sample_id))
                                                for i in frame_bytes_list:
                                                    f.writelines(i)
                                                    f.writelines("\n")
                                                logger.info("成功写入异常帧数据！")

                                            logger.info("产品id为{}的帧数据量异常，存入异常文件中，不向Java传输周期数据".format(sample_id))
                                            frame_bytes_list = []
                                            # del self.__pressure_frame_list[0:frame_list_len - 4]
                                            self.del_data()
                                            self.actual_settings_pressure_speed_list = []
                                            self.processing_signal_data_list = []
                                            continue  # 跳过此次循环之前并没有对data_bytes的第一条数据进行删除
                                        frame_bytes_list = []

                                        # with open("//usr//local//src//webroot//detecter//data//test.csv", "a+") as f:
                                        # with open(os.path.join(os.getcwd(), "test.csv"), "a+") as f:
                                        #     f.writelines(str(sample_frame_list))
                                        #     f.writelines("\n")
                                        #     print("成功写入！")
                                        # f.close()

                                        # self.sample_frame_list_downsampling = standardized_sampling([list(j) for j in list(np.array(sample_frame_list)[:, [i for i in range(11)]])])  # 进行降采样
                                        # 收集一个产品，上传一个产品，将一个周期中所有的机台实时数据的个数上传给java
                                        # self.add_increment(float(self.statistical_parameter_row_identification_True['周期计时']) * 80)  # 通过print降采样前后sample_frame_list和self.sample_frame_list_downsampling的长度发现周期计算就是按照self.sample_frame_list_downsampling的长度乘以8再除以80得到的。
                                        self.add_increment(int(round(float(self.statistical_parameter_row_identification_True["周期计时"]) * 80, 0)))
                                        # print(len(sample_frame_list))

                                        try:
                                            self.global_shejiaobaoyafendaun = [0]

                                            # 只取 射胶段 和 保压段
                                            df = pd.DataFrame(sample_frame_list_for_other)
                                            sample_frame_list_for_other = df.loc[(df[3] == "00") | (df[3] == "01")].values.tolist()

                                            # # 更新全局的射胶保压分段。这个分段是根据实时的射胶、保压10Hz的数据来分段的，后续的设定值要以它为标准
                                            # actual_location = list(np.array(sample_frame_list_for_other)[:, 3])
                                            # shejiaoduan = 0
                                            # baoya_duan = 0
                                            # for i in range(len(actual_location)):
                                            #     if actual_location[i] == "00":
                                            #         shejiaoduan = i
                                            #     elif actual_location[i] == "01":
                                            #         baoya_duan = i
                                            # self.global_shejiaobaoyafendaun.append(shejiaoduan)  # 这里其实是进行了一个射胶段和保压段的分段标识[0,shejiaodaun,baoya_duan]
                                            #
                                            # self.global_shejiaobaoyafendaun.append(baoya_duan)

                                            # 设定压力、速度数据列表，需要将 实时数据 融合在一起 set_data是机台实时数据
                                            set_data = [list(j) for j in list(np.array(sample_frame_list)[:, [i for i in range(11)]])]
                                            df = pd.DataFrame(set_data)
                                            df[7] = df[7].apply(lambda x: eval(str(x)))  # 第7列  对应射胶保压的信息
                                            set_data = df.loc[df[7] > 10].values.tolist()  # 筛选第七列值大于10的数据，再转成列表。小于10代表不是射胶保压信号，就筛掉

                                            # logger.info(set_data)
                                            # logger.info(sample_frame_list_for_other)
                                            sample_frame_list = self.synchronous_setting_of_real_time_values(set_data, sample_frame_list_for_other)  # 对机台实时信号数据和设置实际压力速度两个列表的数据进行处理
                                            # logger.info(sample_frame_list)

                                            logger.info("射胶结束点")
                                            # 往服务器发送当前样本的数据,服务器要保存每个产品的数据
                                            # network.sample_send(sample_frame_list, self.current_mould.mould_code)  # 同步
                                            current_sample = sample.ProductSample(sample_id, sample_frame_list)  # 创建了一个样本对象，注意这里的sample_frame_list已经和前面的sample_frame_list不一样了
                                            # 保存最近一小时的数据
                                            current_sample.save_in_file(self.current_mould.one_hour_temp_file)  # 将其保存在了一个文件里面
                                            # 处理当前样本
                                            self.current_mould.prod_sample = current_sample  # self.current_mould是当前磨具实例
                                            self.transfer_sample(current_sample)  # 传输样本，如果消费者在运行就添加到样本队列中,如果不在运行，就先添加到对应文件内和数据库中，并记录异常时间。
                                            # 限制__sample_list1的数量，确保在传输数据的线程挂掉后不影响producer，不过多占用内存
                                            if len(self.__sample_list1) < 100:  # 样本队列1里面只存100个样本样本周期吗？这个样本队列1好像没用到！！！
                                                self.__sample_list1.append(current_sample)
                                            else:
                                                self.__sample_list1.pop(0)
                                                self.__sample_list1.append(current_sample)
                                        except Exception as e:
                                            # self.__pressure_frame_list = []
                                            last_50_cycles = []
                                            is_first_sample = True
                                            logger.error(f'样本生成有效信息失败,舍去该样本,{e}')
                                            logger.info(traceback.format_exc())
                                            continue  # 没有对data_bytes里面的数据进行删除
                                            # logger.info(e.__traceback__.tb_frame.f_globals["__file__"])  # 发生异常所在的文件
                                            # logger.info(e.__traceback__.tb_lineno)  # 发生异常所在的行数
                                            # logger.info(traceback.format_exc())  # 发生异常所在的行数

                                        # ############################    上传周期过后的操作     ########################

                                        # 写入配置文件
                                        f = open(os.path.join(os.path.dirname(__file__), "computer_version.json"), 'w', encoding='utf8')
                                        json.dump(self.statistical_parameter_row_identification_True, f, ensure_ascii=False)
                                        f.close()

                                        # 数据集的升采样和降采样、以及数据到consumer分析中
                                        # 一、操作板设置值
                                        set_value = SampleProducer_set_A10.get_instance().set_field_dictionary_supply
                                        set_value = {k: set_value[v] if v in set_value.keys() else None for k, v in chinese_source.items()}
                                        # 二、电脑板统计值
                                        statistical_value = calculate_statistical_values(self.processing_signal_data_list, self.statistical_parameter_row_identification_True)
                                        # 三、温度实时实际值
                                        actual_temperature_value = calculate_the_actual_temperature_value(self.real_time_temperature_data)
                                        # 四、压力速度设定值、实时值
                                        curve_value = real_time_value_of_pressure_and_velocity(sample_frame_list_for_other)
                                        machine_code = settings.MACHINE_CODE.lower()
                                        mode_code = self.current_mould.mould_code
                                        # 将字典中的内容上传至数据库
                                        connect_sql("python_machine", machine_code).insert_mysql_machine(datetime.now(), machine_code, mode_code, str(set_value), str(statistical_value),
                                                                                                         str(actual_temperature_value), str(curve_value), )
                                        logger.info("数据传输成功！！！")
                                    except:
                                        logger.error(traceback.format_exc())
                                # 请注意，这个del_data管理的四个列表要记得清空，否则会不断占用内存。目前在统计参数那里进行了清空
                                # self.del_data()
                    else:
                        logger.info('异或校验未通过')
                else:
                    # logger.warning('数据校验出错: %s' % frame_bytes)
                    # print('数据校验出错: %s' % frame_bytes)
                    pass
                # del data_bytes[0:del_size]  # 每完整地处理一条数据完成之后就删除databytes的一条数据

        self.__data_bytes.clear()
        self.__data_bytes_part.clear()
        # 结束清空
        self.stop()
        logger.warning("样本采集线程SampleProducer_actual_values_A10退出")

    def receive_packets(self, socket_TF):
        while self.socket_TF:
            try:
                self.recv_handle_queue.put(self.process_queue.get())
            except Exception as e:
                pass

    def handle_temporary_data(self):
        while True:
            # if len(self.temporary_data)>0:
            try:
                data = self.recv_handle_queue.get()
                frame_bytes1 = data.hex().upper()
                frame_bytes = frame_bytes1[56:]  # 这前面56个字节是包头等信息，从索引56开始后面是我们需要的data
                temp_bytes = bytes.fromhex(frame_bytes)
                frame_bytes = temp_bytes[0:int(16 / 2)].hex().upper()  # 16位
                if (frame_bytes[:10] == self.Verification_List[3][:10] and frame_bytes[-4:] == self.Verification_List[3][-4:]) or temp_bytes[0:int(8 / 2)].hex().upper() in self.Verification_List:
                    self.q.put(temp_bytes)
                    # self.__data_bytes = self.__data_bytes + temp_bytes
                    if self.q.qsize() > 29000:
                        logger.info(
                            'self.q出现数据累积，已超过29000，为{}'.format(self.q.qsize()))
                if frame_bytes1[24:32] == "C0A803D3" and frame_bytes[:8] in self.Verification_List_set:  # C0A803D3是一个源地址
                    SampleProducer_set_A10.get_instance().q_set.put(temp_bytes)
            except:
                logger.info(traceback.format_exc())

    def synchronous_setting_of_real_time_values(self, set_data, sample_frame_list_for_other):
        # 一、8Hz的9001合并到17Hz的3C00中，8Hz到17Hz，取螺杆位置曲线数据
        # 二、17Hz二维数据缩放到10Hz并返回

        # ['2024-02-18 15:24:26.364260', 1708241066364, 0, 10, 10, 0, 0.0, 0, 0, 0, 1, 0]
        # 时间、时间戳、帧序列、设定压力、设定速度、实际压力、实际螺杆、射胶（保压）、储料、射退、合模（开模）、实际速度

        all_list = []
        # 压力速度实际设置值和螺杆位置值 统一帧数
        actual_settings_pressure_speed_list = sample_frame_list_for_other
        actual_pressure = list(np.array(actual_settings_pressure_speed_list)[:, 4])  # 得到的是一个列表 array :[1 2 3]-->list : [1, 2, 3]
        actual_speed = list(np.array(actual_settings_pressure_speed_list)[:, 5])
        set_pressure = list(np.array(actual_settings_pressure_speed_list)[:, 6])
        set_speed = list(np.array(actual_settings_pressure_speed_list)[:, 7])

        # 下面这是向all_list里面添加了六个列表，每一个列表里面存储着相同类型的数据，列表与列表之间存储的是不同类型的数据
        all_list.append(list(np.array(actual_settings_pressure_speed_list)[:, 0]))  # 时间
        all_list.append(list(np.array(actual_settings_pressure_speed_list)[:, 1]))  # 时间戳
        all_list.append(list(np.array(actual_settings_pressure_speed_list)[:, 2]))  # 帧序列
        all_list.append(set_pressure)  # 设定压力
        all_list.append(set_speed)  # 设定速度
        all_list.append(actual_pressure)  # 实际压力

        # 关于螺杆位置对齐的算法
        # 先放大字段  len(actual_loc)=len(all_list[0])*len(set_data)
        actual_loc = []
        for i in range(len(set_data)):  # 遍历螺杆位置字段
            for j in range(len(all_list[0])):  # 根据all_list中，一个子列表的长度决定对螺杆位置取几次值。最后，actual_loc的长度应该是set_data长度的len(all_list[0])倍。
                actual_loc.append(set_data[i][6])  # 下标为6的是螺杆位置

        # 再缩小字段   将actual_loc缩小len(set_data)倍，可以保证actual_loc的长度和其他各个子列表的长度相等
        actual_loc_new = []
        for i in range(0, len(actual_loc), len(set_data)):
            actual_loc_new.append(actual_loc[i])

        all_list.append(actual_loc_new)  # 实际螺杆 往all_list里面添加一个螺杆位置列表
        all_list.append([1 if i == "00" else 0 for i in list(np.array(actual_settings_pressure_speed_list)[:, 3])])  # 射胶（保压）
        all_list.append([1 if i == "04" else 0 for i in list(np.array(actual_settings_pressure_speed_list)[:, 3])])  # 储料
        all_list.append([1 if i == "07" else 0 for i in list(np.array(actual_settings_pressure_speed_list)[:, 3])])  # 开模
        all_list.append([1 if i == "06" else 0 for i in list(np.array(actual_settings_pressure_speed_list)[:, 3])])  # 合模
        all_list.append(actual_speed)  # 实际速度

        aaa = np.array(all_list).T  # 将二维数组进行了一个转置，转置之后，一个子列表里面存储的就是从时间到实际速度，各种类型的数据了

        # 规整频率到10Hz  ，  从17Hz到10Hz
        aaa_170Hz = []
        for i in range(len(aaa)):  # 将aaa里面的每一条数据取10次添加到aaa_170HZ这个空列表里面，相当于乘了10倍,升到170HZ
            for j in range(10):
                aaa_170Hz.append(aaa[i])

        aaa_10Hz = []
        for i in range(0, len(aaa_170Hz), 17):  # 除以17倍，就相当于降到了10HZ
            aaa_10Hz.append(aaa_170Hz[i])
        aaa = aaa_10Hz

        self.global_shejiaobaoyafendaun = [0]
        # 更新全局的射胶保压分段。这个分段是根据实时的射胶、保压10Hz的数据来分段的，后续的设定值要以它为标准
        actual_location = list(np.array(aaa)[:, 7])  # 射胶保压的分段要根据降频后的数据来取。虽然不明白为什么要降频
        shejiaoduan = 0
        baoya_duan = 0
        for i in range(len(actual_location)):
            if actual_location[i] == "1":
                shejiaoduan = i
            elif actual_location[i] == "0":
                baoya_duan = i
        self.global_shejiaobaoyafendaun.append(shejiaoduan)  # 这里其实是进行了一个射胶段和保压段的分段标识[0,shejiaodaun,baoya_duan]
        self.global_shejiaobaoyafendaun.append(baoya_duan)


        df = pd.DataFrame(aaa)
        for i in range(1, len(aaa[0])):  # 将每一列数据进行一个格式转换
            df[i] = df[i].apply(lambda x: eval(str(x)))

        return df.values.tolist()  # 将 每一行的值转成一个子列表，所有的子列表放在一个大列表里面，作为值返回。

    def del_data(self):
        # del self.processing_signal_data_list[0:len(self.processing_signal_data_list) - 4]  # 保留下一帧开始的4帧没有丢失
        # del self.actual_settings_pressure_speed_list[0:len(self.actual_settings_pressure_speed_list) - 4]  # 保留下一帧开始的4帧没有丢失
        self.scqd, self.scjy, self.cljy, self.zdss = [], [], [], []

    # 初始化

    # 信息分类添加、集成
    def add_data_to_list(self, frame_bytes, pressure_size):
        frame_arr = []
        # 去找对应方法解析
        if frame_bytes[:10] == "0200980100" and frame_bytes[12:16] == "4243":  # 实时温度数据                   全过程
            self.real_time_temperature_data = nozzle_temperature_1_8(frame_bytes, self.real_time_temperature_data)

        elif frame_bytes[:pressure_size] == "02003C00":  # 处理实时压力、速度、设置压力、设置速度            全过程
            # self.jishu += 1
            # print(self.jishu)
            # i = 0
            # self.actual_settings_pressure_speed_list.append(actual_settings_pressure_speed(frame_bytes, i))
            p = 1  # 取17 * 5 帧  其实是可以取17*6帧的，但考虑到会有06 00 00 00 00的情况，而且很多地方取值5个数组进行校验，所以选取 乘以5 帧
            exemption_from_verification = False
            for i in range(p):
                res = actual_settings_pressure_speed(frame_bytes, i)
                # with open("//usr//local//src//webroot//detecter//data//test.csv", "a+") as f:
                #     f.writelines(str(res))
                #     # f.writelines(str(frame_bytes))
                #     f.writelines("\n")
                #     print("成功写入！")
                # f.close()

                # res[3] != "06" 是因为在判断一个周期的时候用到了合模 06 这个信号，而在原始数据中，按照17Hz*6的标准来过滤，会将06 00 00 00 00 00这一标识行忽略，导致无法分隔每一模周期的切割
                if not exemption_from_verification:  # 函数每一次到这里来时，都只会走if,不会走else.   这里可能有问题
                    if res[3] != "06" and res[4] == 0 and res[5] == 0 and res[6] == 0 and res[7] == 0.0 and res[8] == 0:  # 查看源数据发现 会有  空字段 0 0 0 0.0 0
                        # 如果不等于06，就不是合模信号，后面的各个参数值如果是0  不进行处理
                        pass
                    elif res[3] == "06" and res[4] == 0 and res[5] == 0 and res[6] == 0 and res[7] == 0.0 and res[8] == 0:  # 查看源数据发现 会有  空字段 0 0 0 0.0 0
                        # 例如：['2024-04-09 09:29:58.803272', 1712626198803, 0, '06', 0, 0, 0, 0.0, 0]        #这条数据是一个合模信号
                        exemption_from_verification = True  # 当循环只执行一次时，这个值应该是多余的
                        self.actual_settings_pressure_speed_list.append(res)
                    else:
                        self.actual_settings_pressure_speed_list.append(res)
                else:
                    self.actual_settings_pressure_speed_list.append(res)

        elif frame_bytes[:pressure_size] == "02004E00":  # 统计参数  时间、起点、终点、压力、速度     全过程
            self.processing_statistical_data(frame_bytes)

        elif frame_bytes[:pressure_size] == "02009001":  # 实时机台信号数据                   全过程
            self.processing_signal_data_list.append(self.processing_signal_data(frame_bytes))

    # 信号数据
    # @staticmethod
    def processing_signal_data(self, frame_bytes):

        # round(int((frame_bytes[22:26] + frame_bytes[22:26][:2])[-4:], 16) / 10, 1)
        frame_arr = []
        frame_arr_signal = [0, 0, 0, 0]  # 4个0是用来占位的，到时候用来存储对应的动作信号数据
        # 日期 0
        frame_arr.append(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')),  # 日期 0
        # 时间戳 1  毫秒级别
        frame_arr.append(int(round(time.time() * 1000)))  # 时间戳 1  毫秒级别
        # 帧序列号自行标记
        # 帧序列号 2
        frame_arr.append(0)  # 帧序列号,每秒80帧 2
        # 设定压力 3
        frame_arr.append(0)  # 暂时用0代替
        # 设定速度 4
        frame_arr.append(0)  # 暂时用0代替
        # 实际压力 5
        frame_arr.append(0)  # 暂时用0代替
        # 螺杆位置 6
        frame_arr.append(round(int((frame_bytes[588:592] + frame_bytes[588:592][:2])[-4:], 16) / 10, 1))  # 暂时用0代替

        # 动作信号
        if frame_bytes[28:32] == "0800" and frame_bytes[50:52] != "00":  # 射胶  7
            if frame_bytes[50:52] == "01":  # 射胶一段
                frame_arr_signal[0] = 11
            elif frame_bytes[50:52] == "02":
                frame_arr_signal[0] = 12
            elif frame_bytes[50:52] == "03":
                frame_arr_signal[0] = 13
            elif frame_bytes[50:52] == "04":
                frame_arr_signal[0] = 14
            elif frame_bytes[50:52] == "05":
                frame_arr_signal[0] = 15
            elif frame_bytes[50:52] == "06":
                frame_arr_signal[0] = 16
            elif frame_bytes[50:52] == "07":
                frame_arr_signal[0] = 17
            elif frame_bytes[50:52] == "08":
                frame_arr_signal[0] = 18
            elif frame_bytes[50:52] == "09":
                frame_arr_signal[0] = 19
        elif frame_bytes[28:32] == "0840" and frame_bytes[50:52] != "00":  # 保压  7
            if frame_bytes[50:52] == "01":  # 保压一段
                frame_arr_signal[0] = 21
            elif frame_bytes[50:52] == "02":
                frame_arr_signal[0] = 22
            elif frame_bytes[50:52] == "03":
                frame_arr_signal[0] = 23
            elif frame_bytes[50:52] == "04":
                frame_arr_signal[0] = 24
            elif frame_bytes[50:52] == "05":
                frame_arr_signal[0] = 25
            elif frame_bytes[50:52] == "06":
                frame_arr_signal[0] = 26
            elif frame_bytes[50:52] == "07":
                frame_arr_signal[0] = 27
            elif frame_bytes[50:52] == "08":
                frame_arr_signal[0] = 28
            elif frame_bytes[50:52] == "09":
                frame_arr_signal[0] = 29
        elif frame_bytes[28:32] == "2000":  # 储料  8
            frame_arr_signal[1] = 1
        elif frame_bytes[28:32] == "1000":  # 射退  9
            frame_arr_signal[2] = 1
        elif frame_bytes[28:32] == "0100":  # 合模  10
            frame_arr_signal[3] = 1
        elif frame_bytes[28:32] == "0400":  # 开模  10
            frame_arr_signal[3] = 4
        frame_arr.extend(frame_arr_signal)
        # 机台状态信号  11
        frame_arr.append(frame_bytes[24:26])

        # 动作信号冷却信号    托模信号   12
        frame_arr.append(frame_bytes[32:36])

        # # 托模信号  13
        # frame_arr.append(frame_bytes[30:34])

        return frame_arr

    # 统计参数
    def processing_statistical_data(self, frame_bytes):
        # round(int((frame_bytes[22:26] + frame_bytes[22:26][:2])[-4:], 16) / 10, 1)
        # with open("//usr//local//src//webroot//detecter//data//test672.txt", "a+") as f:  ##不要在这里进行写操作，耗时严重，会严重丢帧！！！！！！！！！！！
        #     f.write(frame_bytes)
        #     f.write("哈哈哈哈哈\n")
        #     print("成功写入！")
        frame_arr = self.statistical_parameter_row_identification
        computer_board_timing_N = round(int((frame_bytes[24:28] + frame_bytes[24:28][:2])[-4:], 16) / 100, 2)  # 第N帧的 计时
        if computer_board_timing_N < self.computer_board_timing:  # 如果第N帧的计时  小于  前一帧的计时  说明 第N帧  是计时 起头的第一帧

            # 取本周期内最大值
            '''注意这里周期的第一点进来以后，所有的数据都没有被记录。目前还没有做修改
            '''
            self.computer_board_timing = computer_board_timing_N
            if self.scqd:
                self.statistical_parameter_row_identification["射出起点"] = str(max(self.scqd))
            else:
                self.statistical_parameter_row_identification["射出起点"] = ""
            if self.scjy:
                self.statistical_parameter_row_identification["射出尖压"] = str(max(self.scjy))
            else:
                self.statistical_parameter_row_identification["射出尖压"] = ""
            if self.cljy:
                self.statistical_parameter_row_identification["储料尖压"] = str(max(self.cljy))
            else:
                self.statistical_parameter_row_identification["储料尖压"] = ""
            if self.zdss:
                self.statistical_parameter_row_identification["最大射速"] = str(max(self.zdss))
            else:
                self.statistical_parameter_row_identification["最大射速"] = ""
            # 取下一周期第一点
            self.statistical_parameter_row_identification["取件时间"] = str(round(int((frame_bytes[208:212] + frame_bytes[208:212][:2])[-4:], 16) / 100, 2))
            self.statistical_parameter_row_identification_True = copy.deepcopy(self.statistical_parameter_row_identification)
            #将那四个列表清空
            self.del_data()

        else:
            self.computer_board_timing = computer_board_timing_N
            frame_arr["周期计时"] = str(round(int((frame_bytes[24:28] + frame_bytes[24:28][:2])[-4:], 16) / 100, 2))
            frame_arr["注射保压时间"] = str(round(int((frame_bytes[32:36] + frame_bytes[32:36][:2])[-4:], 16) / 100, 2))
            frame_arr["射出时间"] = str(round(int((frame_bytes[40:44] + frame_bytes[40:44][:2])[-4:], 16) / 100, 2))
            frame_arr["储料时间"] = str(round(int((frame_bytes[48:52] + frame_bytes[48:52][:2])[-4:], 16) / 100, 2))
            frame_arr["合模时间"] = str(round(int((frame_bytes[56:60] + frame_bytes[56:60][:2])[-4:], 16) / 100, 2))
            frame_arr["合模低压时间"] = str(round(int((frame_bytes[60:64] + frame_bytes[60:64][:2])[-4:], 16) / 100, 2))
            frame_arr["合模高压时间"] = str(round(int((frame_bytes[64:68] + frame_bytes[64:68][:2])[-4:], 16) / 100, 2))
            frame_arr["开模时间"] = str(round(int((frame_bytes[68:72] + frame_bytes[68:72][:2])[-4:], 16) / 100, 2))
            frame_arr["开模位置"] = str(round(int((frame_bytes[72:76] + frame_bytes[72:76][:2])[-4:], 16) / 10, 1))
            # frame_arr["射胶信号"] = frame_bytes[86:90]
            frame_arr["射出终点"] = str(round(int((frame_bytes[96:100] + frame_bytes[96:100][:2])[-4:], 16) / 10, 1))
            frame_arr["射出监控"] = str(round(int((frame_bytes[104:108] + frame_bytes[104:108][:2])[-4:], 16) / 10, 1))
            frame_arr["转保压力"] = str(int((frame_bytes[120:124] + frame_bytes[120:124][:2])[-4:], 16))
            frame_arr["最大储料转速"] = str(int((frame_bytes[124:128] + frame_bytes[124:128][:2])[-4:], 16))
            frame_arr["射退时间"] = str(round(int((frame_bytes[128:132] + frame_bytes[128:132][:2])[-4:], 16) / 100, 2))
            frame_arr["托模时间"] = str(round(int((frame_bytes[132:136] + frame_bytes[132:136][:2])[-4:], 16) / 100, 2))
            frame_arr["顶进时间"] = str(round(int((frame_bytes[148:152] + frame_bytes[148:152][:2])[-4:], 16) / 100, 2))
            frame_arr["顶退时间"] = str(round(int((frame_bytes[152:156] + frame_bytes[152:156][:2])[-4:], 16) / 100, 2))

            # frame_arr["取件时间"] = str(round(int((frame_bytes[150:154] + frame_bytes[150:154][:2])[-4:], 16) / 100, 2))

            frame_arr["保压时间"] = str(round(int((frame_bytes[280:284] + frame_bytes[280:284][:2])[-4:], 16) / 100, 2))
            frame_arr["冷却时间"] = str(round(int((frame_bytes[284:288] + frame_bytes[284:288][:2])[-4:], 16) / 100, 2))

            self.scqd.append(round(int((frame_bytes[110:114] + frame_bytes[110:114][:2])[-4:], 16) / 10, 1))
            self.scjy.append(int((frame_bytes[140:144] + frame_bytes[140:144][:2])[-4:], 16))
            self.cljy.append(int((frame_bytes[144:148] + frame_bytes[144:148][:2])[-4:], 16))
            self.zdss.append(int((frame_bytes[216:220] + frame_bytes[216:220][:2])[-4:], 16))

            self.statistical_parameter_row_identification = frame_arr

    @staticmethod
    def verify_dictionary(frame_bytes, verification_List, verification_List_del_len):
        # 当前六位不在解析的列表中，直接跳过
        if frame_bytes not in verification_List:
            del_len = 1
            return False, del_len
        else:
            for i, j in enumerate(verification_List):
                if frame_bytes == j:
                    del_len = verification_List_del_len[i]
                    return True, int(del_len / 2)

    # 统计周期区间
    @staticmethod
    def statistical_cycle_interval(Last_50_cycles, zhenshu):  # 将周期列表、设置样本长度传过来
        # logger.info("周期列表个数{}，到{}，周期帧数限制".format(len(Last_50_cycles), zhenshu))
        dict_qujian = {}
        for i in Last_50_cycles:
            dict_qujian[str(i // 5)] = 0
        for i in Last_50_cycles:
            dict_qujian[str(i // 5)] += 1
        ans = max(dict_qujian, key=lambda x: dict_qujian[x])
        standard_cycle = (eval(ans) + 1) * 5
        # logger.info("落在多数区间的上限值是{}s".format(standard_cycle))
        return standard_cycle

    @staticmethod
    def add_increment(frame_length=None):
        update_product(UpdateType.ADD_GOOD, frame_length=frame_length)

    # 模拟及开关信号示例数据
    @staticmethod
    def is_pressure_frame(unknown_bytes):  # 0:帧头, 1:dest,3:数据长度, 17:帧尾
        check_bytes = unknown_bytes[1:18]  # 从第2字节到第16字节, 需要校验的字节段
        check_result = unknown_bytes[18]  # 第17字节, 异或校验和
        if unknown_bytes[0] == 0xAA and unknown_bytes[1] == 0xff and unknown_bytes[3] == 18 \
                and unknown_bytes[4] == 0x01 and unknown_bytes[19] == 0xAA:
            bbc = 0x00  # 0异或任何数为任何数本身
            for byte in check_bytes:
                bbc ^= byte
            return bbc == check_result
        else:
            return False

    # K型热电偶温度示例数据
    @staticmethod
    def is_temp_frame(unknown_bytes):
        check_bytes = unknown_bytes[1:13]
        check_result = unknown_bytes[13]
        if unknown_bytes[0] == 0xAA and unknown_bytes[1] == 0xff and unknown_bytes[3] == 13 \
                and unknown_bytes[4] == 0x02 and unknown_bytes[14] == 0xAA:
            bbc = 0x00  # 0异或任何数为任何数本身
            for byte in check_bytes:
                bbc ^= byte
            return bbc == check_result
        else:
            return False

    # 1后面5个0 才能确定是一个产品的结束
    # 10是开模，9是射退
    @staticmethod
    def is_product_begin(check_frames):
        current_frame = check_frames[0]
        check_frame_list = check_frames[1:5]
        if int(current_frame[10]) == 1:
            flag = True
            for frame in check_frame_list:
                if int(frame[10]) == 1:
                    flag = False
                    break
        else:
            flag = False
        return flag

    # 1后面5个0 才能确定是一个产品的结束
    # 10是开模，9是射退
    @staticmethod
    def is_product_begin_for_other(check_frames):
        current_frame = check_frames[0]
        check_frame_list = check_frames[1:5]
        if str(current_frame[3]) == "06":
            flag = True
            for frame in check_frame_list:
                if str(frame[3]) == "06":
                    flag = False
                    break
        else:
            flag = False
        return flag

    @staticmethod
    def calc_crc(string):
        data = bytearray.fromhex(string)
        # print(data)
        crc = 0xFFFF  # 初始值
        for pos in data:
            crc ^= pos  # 每次两位16进制和crc低8位异或
            for i in range(8):  # 右移八次
                if (crc & 1) != 0:  # 如果移出去的不是0（即移出去的是1）则右移1位且和A001异或。否则为0直接右移1位不作其他处理
                    crc >>= 1
                    crc ^= 0xA001
                else:
                    crc >>= 1
        ret = hex(((crc & 0xff) << 8) + (crc >> 8))[2:]  # 高低8位对调。
        if len(ret) != 4:
            ret = '0' * (4 - len(ret)) + ret
        return ret

    @staticmethod
    def transfer_pressure_frame_to_arr(frame_bytes):
        frame_arr = []
        # 日期 0
        frame_arr.append(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')),  # 日期 0
        # 时间戳 1  毫秒级别
        frame_arr.append(int(round(time.time() * 1000)))  # 时间戳 1  毫秒级别
        # 帧序列号自行标记
        # 帧序列号 2
        frame_arr.append(0)  # 帧序列号,每秒80帧 2
        # 设定压力 3
        frame_arr.append(round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[6:14]))))[0], 10))  # 设定压力 3
        # 设定速度 4
        frame_arr.append(round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[14:22]))))[0], 10))  # 设定速度 4
        # 实际压力 5
        frame_arr.append(round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[22:30]))))[0], 10))  # 实际压力 5
        # 螺杆位置 6
        frame_arr.append(round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[30:38]))))[0], 10))  # 螺杆位置 6

        sj = 1
        if round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[38:46]))))[0], 10) >= 22:
            sj = 0
        # 射胶信号 7
        frame_arr.append(sj)  # 射胶信号 7  # 电压值大于22V为1，小于2V为0

        cl = 1
        if round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[46:54]))))[0], 10) >= 22:
            cl = 0
        # 储料信号 8
        frame_arr.append(cl)  # 储料信号 8

        st = 1
        if round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[54:62]))))[0], 10) >= 22:
            st = 0
        # 射退信号 9
        frame_arr.append(st)  # 射退信号 9

        km = 1
        if round(struct.unpack('<f', struct.pack('<I', eval('0x' + (frame_bytes[62:70]))))[0], 10) >= 22:
            km = 0
        # 开模信号 10  # 电压值大于22V为1，小于2V为0
        frame_arr.append(km)
        return frame_arr

    @staticmethod
    def temp_frames_to_arr(tem_bytes):
        tem_arr = list()
        tem_arr.append(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))  # 日期
        tem_arr.append(int(round(time.time() * 1000)))  # 时间戳
        tem_arr.append(tem_bytes[5] * 256 + tem_bytes[6])  # 第一段温度
        tem_arr.append(tem_bytes[7] * 256 + tem_bytes[8])  # 第二段温度
        tem_arr.append(tem_bytes[9] * 256 + tem_bytes[10])  # 第三段温度
        tem_arr.append(tem_bytes[11] * 256 + tem_bytes[12])  # 第三段温度
        return tem_arr


class UpdateType(Enum):
    ADD_GOOD = 2
    ADD_BAD = 3
    POS_FEEDBACK = 1  # 良品+1同时不良品-1
    NEG_FEEDBACK = -1  # 不良+1 同时良品-1


def bytes2hex(frame_bytes):
    hex_bytes = binascii.b2a_hex(frame_bytes)
    frame_bytes_str = hex_bytes.decode('utf-8').upper()
    return frame_bytes_str


def update_product(update_type=UpdateType.ADD_GOOD, frame_length=None):
    url = settings.SERVER_URL
    pad_url = '{}/pad/pad'.format(url)
    product_url = f"{pad_url}/updateNew/{settings.MACHINE_CODE}/{frame_length}"  # MACHINE_CODE在pycharm的配置文件中的值为A09，但是在平板上时，配置文件是不一样的，传入的是对应的平板的编号
    get(product_url, None)


def get(url, data):
    try:
        response = requests.get(url, data, timeout=(3.05, 27))
        # response = requests.put(url, data, timeout=(3.05, 27))
        OK_CODE = 200
        if response.status_code == OK_CODE:
            logger.info(f'{url}:{response.json()}')
            result = analyse_response(response.json())
            # by zxy on 20191114
            response.close()
            return result
        else:
            logger.error(f"{response},网络异常,无法成功访问接口")
    except Exception as e:
        logger.error(e)


def analyse_response(result):
    SUCCESS_CODE = 0
    if result["code"] == SUCCESS_CODE:
        return result["data"]
    else:
        logger.error(result['msg'])
